#ifndef AGENT_H
#define AGENT_H

#include "CollidableObject.h"
#include "StringUtility.h"
#include "Singleton.h"
#include "SteeringBehaviour.h"
#include <map>
#include <cmath>
#include <vector>

namespace Engine
{
	namespace GameObjectTypes
	{
		const unsigned int AGENT = Hash("Agent");
	}

	class AgentGroup;
	class Agent;

	typedef std::vector <Agent*> Agents;

	class Agent : public CollidableObject
	{
		protected:
			Agent* m_target;
			typedef std::map <unsigned int, WeightedSteeringBehaviour> SteeringBehaviourMap;
			SteeringBehaviourMap m_steeringBehaviourMap;

			AgentGroup* m_group;

		public:
			virtual ~Agent();
			
			//inherited from GameObject
			virtual void Update() override;
			virtual const char* GetTypeName() const override {return "Agent";}
			virtual unsigned int GetTypeHash() const override {return GameObjectTypes::AGENT;}
			virtual void Initialize() override;
			virtual void Release() override;
			virtual void Draw() override;

			Agent();

			void AddSteeringBehaviour(const WeightedSteeringBehaviour &b, Agent* target);
			SteeringBehaviour* GetSteeringBehaviour(unsigned int hash);
			void RemoveSteeringBehaviour(unsigned int hash);
			
			//setters and getters
			void SetTarget(Agent* t) {m_target = t;}
			void SetGroup(AgentGroup* g) {m_group = g;}
			Agent* GetTarget() {return m_target;}
			AgentGroup* GetGroup() {return m_group;}

			Vec3 GetRotAsVector()
			{
				return Engine::Vec3(sin(m_rot), 0, cos(m_rot));
			}

			Vec3 PredictFuturePosition(const float predictionTime) const
			{
				return m_pos + (m_vel * predictionTime);
			}
	};
}

#endif